// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   Chart.java

package com.java4less.rchart;

import com.java4less.rchart.gc.ChartColor;
import com.java4less.rchart.gc.ChartFont;
import com.java4less.rchart.gc.ChartGraphics;
import com.java4less.rchart.gc.ChartImage;
import com.java4less.rchart.gc.GraphicsProvider;
import com.java4less.rchart.gc.Polygon;
import java.io.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart:
//			Plotter, Title, TargetZone, BarPlotter3D, 
//			LinePlotter3D, Legend, ChartListener, LineDataSerie, 
//			ChartLabel, Axis, Scale, HAxisLabel, 
//			VAxisLabel, FillStyle, LineStyle, DataSerie, 
//			ChartLoader, IFloatingObject

public class Chart
{
	private class Updater
		implements Runnable
	{

		public boolean stop;
		public Chart chart;
		final Chart this$0;

		public void run()
		{
			System.out.println("Starting loop");
			do
			{
				if (stop)
					break;
				try
				{
					Thread.sleep(msecs);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
				if (stop)
					break;
				try
				{
					triggerEvent(0);
					if (autoRebuild)
						loader.build(Chart.this, false, false);
					triggerEvent(1);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			} while (true);
		}

		private Updater()
		{
			this$0 = Chart.this;
			super();
			stop = false;
			chart = null;
		}

	}


	public static final int LAYOUT_LEGEND_RIGHT = 0;
	public static final int LAYOUT_LEGEND_TOP = 1;
	public static final int LAYOUT_LEGEND_BOTTOM = 2;
	public String onClickJSFunction;
	protected static final int MAX_SERIES = 50;
	public static final int dnum = 10;
	public static String numberLocale;
	public VAxisLabel YLabel;
	public VAxisLabel Y2Label;
	public HAxisLabel XLabel;
	public Legend legend;
	public Axis XAxis;
	public Axis YAxis;
	public Axis Y2Axis;
	public Title title;
	public double bottomMargin;
	public double topMargin;
	public double secondYAxisMargin;
	public double leftMargin;
	public double rightMargin;
	public double legendMargin;
	public double axisMargin;
	public boolean autoSize;
	public Plotter plotters[];
	private int plottersCount;
	public int layout;
	public FillStyle back;
	public LineStyle border;
	public int offsetX;
	public int offsetY;
	private int width;
	private int height;
	private int minimumWidth;
	private int minimumHeight;
	public ChartImage backImage;
	private ChartImage chartImage;
	private ChartImage finalImage;
	private ChartImage backTmpImage;
	public boolean doubleBuffering;
	public int virtualWidth;
	public int virtualHeight;
	private int originalVirtualWidth;
	private int originalVirtualHeight;
	public boolean withScroll;
	public boolean repaintAll;
	public boolean repaintAlways;
	private Vector chartListeners;
	public boolean fullXAxis;
	public ChartLabel selectedLabel;
	public DataSerie selectedSerie;
	public int selectedSeriePoint;
	private int lastWidth;
	private int lastHeight;
	public boolean activateSelection;
	public int currentX;
	public int currentY;
	public double currentValueX;
	public double currentValueY;
	public double currentValueY2;
	private boolean showingTip;
	ChartColor tipColor;
	ChartColor tipFontColor;
	ChartFont tipFont;
	private int cursorLastX;
	private int cursorLastY;
	public String htmlLinkTarget;
	public boolean showTips;
	public boolean showPosition;
	public ChartLoader loader;
	public long msecs;
	private boolean stopped;
	public String reloadFrom;
	public boolean autoRebuild;
	private Updater deamon;
	protected Vector targetZones;
	protected Vector notes;
	protected Vector chartHotAreas;
	protected Vector floatingObjects;

	public Chart(Title t, Plotter p, Axis X, Axis Y)
	{
		onClickJSFunction = "OnClickRChart";
		bottomMargin = 0.125D;
		topMargin = 0.125D;
		secondYAxisMargin = 0.0D;
		leftMargin = 0.125D;
		rightMargin = 0.125D;
		legendMargin = 0.20000000000000001D;
		axisMargin = 0.0625D;
		autoSize = true;
		plotters = new Plotter[10];
		plottersCount = 0;
		layout = 0;
		back = null;
		border = null;
		offsetX = 0;
		offsetY = 0;
		width = 0;
		height = 0;
		minimumWidth = 0;
		minimumHeight = 0;
		chartImage = null;
		finalImage = null;
		backTmpImage = null;
		doubleBuffering = true;
		virtualWidth = 0;
		virtualHeight = 0;
		originalVirtualWidth = -1;
		originalVirtualHeight = -1;
		withScroll = false;
		repaintAll = true;
		repaintAlways = true;
		chartListeners = new Vector();
		fullXAxis = false;
		selectedLabel = null;
		selectedSerie = null;
		selectedSeriePoint = -1;
		lastWidth = -1;
		lastHeight = -1;
		activateSelection = false;
		showingTip = false;
		tipColor = GraphicsProvider.getColor(ChartColor.YELLOW);
		tipFontColor = GraphicsProvider.getColor(ChartColor.BLACK);
		tipFont = GraphicsProvider.getFont("Serif", ChartFont.PLAIN, 10);
		cursorLastX = 0;
		cursorLastY = 0;
		htmlLinkTarget = "";
		showTips = false;
		showPosition = false;
		loader = null;
		msecs = 2000L;
		stopped = false;
		reloadFrom = "";
		autoRebuild = true;
		deamon = null;
		targetZones = new Vector();
		notes = new Vector();
		chartHotAreas = new Vector(0, 5);
		floatingObjects = new Vector(0, 5);
		resetChart(t, p, X, Y);
	}

	protected Chart()
	{
		onClickJSFunction = "OnClickRChart";
		bottomMargin = 0.125D;
		topMargin = 0.125D;
		secondYAxisMargin = 0.0D;
		leftMargin = 0.125D;
		rightMargin = 0.125D;
		legendMargin = 0.20000000000000001D;
		axisMargin = 0.0625D;
		autoSize = true;
		plotters = new Plotter[10];
		plottersCount = 0;
		layout = 0;
		back = null;
		border = null;
		offsetX = 0;
		offsetY = 0;
		width = 0;
		height = 0;
		minimumWidth = 0;
		minimumHeight = 0;
		chartImage = null;
		finalImage = null;
		backTmpImage = null;
		doubleBuffering = true;
		virtualWidth = 0;
		virtualHeight = 0;
		originalVirtualWidth = -1;
		originalVirtualHeight = -1;
		withScroll = false;
		repaintAll = true;
		repaintAlways = true;
		chartListeners = new Vector();
		fullXAxis = false;
		selectedLabel = null;
		selectedSerie = null;
		selectedSeriePoint = -1;
		lastWidth = -1;
		lastHeight = -1;
		activateSelection = false;
		showingTip = false;
		tipColor = GraphicsProvider.getColor(ChartColor.YELLOW);
		tipFontColor = GraphicsProvider.getColor(ChartColor.BLACK);
		tipFont = GraphicsProvider.getFont("Serif", ChartFont.PLAIN, 10);
		cursorLastX = 0;
		cursorLastY = 0;
		htmlLinkTarget = "";
		showTips = false;
		showPosition = false;
		loader = null;
		msecs = 2000L;
		stopped = false;
		reloadFrom = "";
		autoRebuild = true;
		deamon = null;
		targetZones = new Vector();
		notes = new Vector();
		chartHotAreas = new Vector(0, 5);
		floatingObjects = new Vector(0, 5);
	}

	protected void resetChart(Title t, Plotter p, Axis X, Axis Y)
	{
		plottersCount = 0;
		plotters = new Plotter[10];
		XAxis = null;
		YAxis = null;
		Y2Axis = null;
		YLabel = null;
		Y2Label = null;
		XLabel = null;
		legend = null;
		title = null;
		border = null;
		back = null;
		selectedSerie = null;
		selectedSeriePoint = -1;
		repaintAll = true;
		removeTargetZones();
		removeNotes();
		chartHotAreas.removeAllElements();
		floatingObjects.removeAllElements();
		plotters[0] = p;
		XAxis = X;
		YAxis = Y;
		if (X != null && plotters[0] != null)
		{
			plotters[0].XScale = X.scale;
			X.plot = plotters[0];
		}
		if (Y != null && plotters[0] != null)
		{
			plotters[0].YScale = Y.scale;
			Y.plot = plotters[0];
		}
		title = t;
		if (title == null)
			title = new Title("");
		plottersCount = 1;
	}

	protected static int d()
	{
		return 0;
	}

	public int getWidth()
	{
		return width;
	}

	public int getHeight()
	{
		return height;
	}

	public void setMinimumSize(int w, int h)
	{
		minimumWidth = w;
		minimumHeight = h;
	}

	public void setSize(int w, int h)
	{
		setWidth(w);
		setHeight(h);
	}

	public void addTargetZone(TargetZone zone)
	{
		targetZones.addElement(zone);
	}

	public void removeTargetZones()
	{
		targetZones.removeAllElements();
	}

	public void addNote(String note)
	{
		notes.addElement(note);
	}

	public void removeNotes()
	{
		notes.removeAllElements();
	}

	public TargetZone[] getTargetZones()
	{
		TargetZone a[] = new TargetZone[targetZones.size()];
		for (int i = 0; i < a.length; i++)
			a[i] = (TargetZone)targetZones.elementAt(i);

		return a;
	}

	protected void paintTargetZones(ChartGraphics g, boolean back)
	{
		g.setFont(GraphicsProvider.getFont("Arial", ChartFont.BOLD, 10));
		for (int i = 0; i < targetZones.size(); i++)
		{
			TargetZone z = (TargetZone)targetZones.elementAt(i);
			z.chart = this;
			z.effect3D = plotters[0].depth;
			if (back && z.background)
				z.paint(g, XAxis, YAxis);
			if (!back && !z.background)
				z.paint(g, XAxis, YAxis);
		}

	}

	public void setWidth(int w)
	{
		if (w > minimumWidth)
			width = w;
	}

	public void setHeight(int h)
	{
		if (h > minimumHeight)
			height = h;
	}

	public void addChartListener(ChartListener cl)
	{
		chartListeners.addElement(cl);
	}

	public void removeChartListener(ChartListener cl)
	{
		chartListeners.removeElement(cl);
	}

	public void removeAllChartListener()
	{
		chartListeners.removeAllElements();
	}

	public void addPlotter(Plotter p)
	{
		plotters[plottersCount] = p;
		plotters[plottersCount].XScale = plotters[0].XScale;
		plotters[plottersCount].YScale = plotters[0].YScale;
		plotters[plottersCount].Y2Scale = plotters[0].Y2Scale;
		plottersCount++;
	}

	public void removePlotters()
	{
		for (int i = 0; i < plottersCount; i++)
			plotters[i] = null;

		plottersCount = 0;
	}

	private void AutoSize()
	{
		if (layout == 0)
			AutoSize_LayoutRight();
		if (layout == 1)
			AutoSize_LayoutTop();
		if (layout == 2)
			AutoSize_LayoutBottom();
	}

	public void setY2Scale(Axis a)
	{
		plotters[0].Y2Scale = a.scale;
		Y2Axis = a;
		a.rightAxis = true;
		a.plot = plotters[0];
	}

	private void setPlotterSize()
	{
		for (int i = 1; i < plottersCount; i++)
		{
			plotters[i].x = plotters[0].x;
			plotters[i].y = plotters[0].y;
			plotters[i].width = plotters[0].width;
			plotters[i].height = plotters[0].height;
		}

	}

	private int getCountParallelAxis(Axis axis)
	{
		if (axis.stackAdditionalAxis)
			return 0;
		else
			return axis.getAdditionalAxisCount();
	}

	private void setPositionStackedAxis(Axis axis)
	{
		if (axis == null)
			return;
		int aCount = axis.getAdditionalAxisCount() + 1;
		if (axis.stackAdditionalAxis && aCount > 1)
			if (axis.orientation == 1)
			{
				int tmpY = axis.y;
				int h = axis.height / aCount;
				int screenMin = axis.scale.screenMin;
				int screenMax = axis.scale.screenMax;
				int screenH = (axis.scale.screenMax - axis.scale.screenMin) / aCount;
				int screenH2 = (axis.scale.screenMaxMargin - axis.scale.screenMin) / aCount;
				int visibleH = axis.visibleSize / aCount;
				tmpY += h;
				screenMin += screenH;
				axis.height = h;
				axis.scale.screenMax = axis.scale.screenMin + screenH;
				axis.scale.screenMaxMargin = axis.scale.screenMin + screenH2;
				axis.visibleSize = visibleH;
				for (int i = 0; i < axis.getAdditionalAxisCount(); i++)
				{
					Axis a = axis.getAdditionalAxis(i);
					a.y = tmpY;
					a.height = h;
					a.scale.screenMin = screenMin;
					a.scale.screenMax = a.scale.screenMin + screenH;
					a.scale.screenMaxMargin = a.scale.screenMin + screenH2;
					a.visibleSize = visibleH;
					a.realPosition = axis.realPosition;
					a.width = axis.width;
					tmpY += h;
					screenMin += screenH;
				}

			} else
			{
				int tmpX = axis.x;
				int w = axis.width / aCount;
				int screenMin = axis.scale.screenMin;
				int screenMax = axis.scale.screenMax;
				int screenW = (axis.scale.screenMax - axis.scale.screenMin) / aCount;
				int screenW2 = (axis.scale.screenMaxMargin - axis.scale.screenMin) / aCount;
				int visibleW = axis.visibleSize / aCount;
				tmpX += w;
				screenMin += screenW;
				axis.width = w;
				axis.scale.screenMax = axis.scale.screenMin + screenW;
				axis.scale.screenMaxMargin = axis.scale.screenMin + screenW2;
				axis.visibleSize = visibleW;
				for (int i = 0; i < axis.getAdditionalAxisCount(); i++)
				{
					Axis a = axis.getAdditionalAxis(i);
					a.x = tmpX;
					a.width = w;
					a.scale.screenMin = screenMin;
					a.scale.screenMax = a.scale.screenMin + screenW;
					a.scale.screenMaxMargin = a.scale.screenMin + screenW2;
					a.visibleSize = visibleW;
					a.realPosition = axis.realPosition;
					a.height = axis.height;
					tmpX += w;
					screenMin += screenW;
				}

			}
	}

	private void AutoSize_LayoutTop()
	{
		int myHeight = getHeight();
		int myWidth = getWidth();
		if (virtualWidth < myWidth)
			virtualWidth = myWidth;
		if (virtualHeight < myHeight)
			virtualHeight = myHeight;
		plotters[0].visibleWidth = (int)((double)myWidth * (1.0D - (leftMargin + rightMargin)));
		plotters[0].visibleHeight = (int)((double)myHeight * (1.0D - (topMargin + legendMargin + bottomMargin)));
		plotters[0].x = (int)((double)myWidth * leftMargin);
		plotters[0].y = (int)((double)myHeight * (topMargin + legendMargin));
		plotters[0].width = virtualWidth - (myWidth - plotters[0].visibleWidth);
		plotters[0].height = virtualHeight - (myHeight - plotters[0].visibleHeight);
		title.x = 0;
		title.y = 0;
		if (XAxis != null && XAxis.xscaleOnTop)
			title.y = virtualHeight - (int)((double)myHeight * bottomMargin);
		title.height = (int)((double)myHeight * topMargin);
		title.width = myWidth;
		if (XAxis != null)
		{
			XAxis.x = (int)((double)myWidth * leftMargin);
			XAxis.y = virtualHeight - (int)((double)myHeight * bottomMargin);
			XAxis.realPosition = (int)((double)myHeight * (1.0D - bottomMargin));
			XAxis.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XAxis.visibleSize = (int)((double)myWidth * (1.0D - (leftMargin + rightMargin)));
			XAxis.width = virtualWidth - (myWidth - XAxis.visibleSize);
		}
		if (YAxis != null)
		{
			YAxis.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
			YAxis.x = (int)((double)myWidth * leftMargin) - YAxis.width;
			YAxis.realPosition = YAxis.x;
			YAxis.y = (int)((double)myHeight * (topMargin + legendMargin));
			YAxis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			YAxis.height = virtualHeight - (myHeight - YAxis.visibleSize);
		}
		if (XLabel != null)
		{
			XLabel.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XLabel.x = (int)((double)myWidth * leftMargin);
			XLabel.y = myHeight - XLabel.height;
			if (XAxis != null && XAxis.xscaleOnTop)
				XLabel.y = (int)((double)myHeight * legendMargin);
			XLabel.width = (int)((double)myWidth * (1.0D - (leftMargin + leftMargin)));
		}
		if (YLabel != null)
		{
			YLabel.x = 0;
			YLabel.y = (int)((double)myHeight * (topMargin + legendMargin));
			YLabel.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			YLabel.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
		}
		if (Y2Axis != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Label != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Axis != null)
		{
			Y2Axis.x = plotters[0].x + plotters[0].width;
			Y2Axis.realPosition = plotters[0].x + plotters[0].visibleWidth;
			Y2Axis.y = (int)((double)myHeight * (topMargin + legendMargin));
			Y2Axis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			Y2Axis.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
			Y2Axis.height = virtualHeight - (myHeight - Y2Axis.visibleSize);
		}
		if (Y2Label != null)
		{
			int tmp = 2 + getCountParallelAxis(Y2Axis);
			Y2Label.x = plotters[0].x + plotters[0].visibleWidth + (int)(((double)myWidth * rightMargin * (double)(tmp - 1)) / (double)tmp);
			Y2Label.y = (int)((double)myHeight * (topMargin + legendMargin));
			Y2Label.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			Y2Label.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
		}
		if (legend != null)
		{
			legend.x = (int)((double)myWidth * leftMargin);
			legend.width = (int)((double)myWidth * (1.0D - (leftMargin + rightMargin)));
			legend.y = (int)((double)myHeight * topMargin);
			if (XAxis != null && XAxis.xscaleOnTop)
				legend.y = 0;
			legend.height = (int)((double)myHeight * legendMargin);
		}
		adjustSize3d();
		setPlotterSize();
	}

	private void AutoSize_LayoutBottom()
	{
		int myHeight = getHeight();
		int myWidth = getWidth();
		if (virtualWidth < myWidth)
			virtualWidth = myWidth;
		if (virtualHeight < myHeight)
			virtualHeight = myHeight;
		plotters[0].visibleWidth = (int)((double)myWidth * (1.0D - (leftMargin + rightMargin)));
		plotters[0].visibleHeight = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
		plotters[0].x = (int)((double)myWidth * leftMargin);
		plotters[0].y = (int)((double)myHeight * topMargin);
		plotters[0].width = virtualWidth - (myWidth - plotters[0].visibleWidth);
		plotters[0].height = virtualHeight - (myHeight - plotters[0].visibleHeight);
		title.x = 0;
		title.y = 0;
		if (XAxis != null && XAxis.xscaleOnTop)
			title.y = virtualHeight - (int)((double)myHeight * (bottomMargin + legendMargin));
		title.height = (int)((double)myHeight * topMargin);
		title.width = myWidth;
		if (XAxis != null)
		{
			XAxis.x = (int)((double)myWidth * leftMargin);
			XAxis.y = virtualHeight - (int)((double)myHeight * (bottomMargin + legendMargin));
			XAxis.realPosition = (int)((double)myHeight * (1.0D - bottomMargin - legendMargin));
			XAxis.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XAxis.visibleSize = (int)((double)myWidth * (1.0D - (leftMargin + rightMargin)));
			XAxis.width = virtualWidth - (myWidth - XAxis.visibleSize);
		}
		if (YAxis != null)
		{
			YAxis.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
			YAxis.x = (int)((double)myWidth * leftMargin) - YAxis.width;
			YAxis.realPosition = YAxis.x;
			YAxis.y = (int)((double)myHeight * topMargin);
			YAxis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			YAxis.height = virtualHeight - (myHeight - YAxis.visibleSize);
		}
		if (XLabel != null)
		{
			int tmp = 2 + getCountParallelAxis(XAxis);
			XLabel.x = (int)((double)myWidth * leftMargin);
			XLabel.y = (int)((double)myHeight * (1.0D - legendMargin)) - (int)((double)myHeight * (bottomMargin / (double)tmp));
			if (XAxis != null && XAxis.xscaleOnTop)
				XLabel.y = 0;
			XLabel.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XLabel.width = (int)((double)myWidth * (1.0D - (leftMargin + leftMargin)));
		}
		if (YLabel != null)
		{
			YLabel.x = 0;
			YLabel.y = (int)((double)myHeight * topMargin);
			YLabel.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			YLabel.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
		}
		if (Y2Axis != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Label != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Axis != null)
		{
			Y2Axis.x = plotters[0].x + plotters[0].width;
			Y2Axis.realPosition = plotters[0].x + plotters[0].visibleWidth;
			Y2Axis.y = (int)((double)myHeight * topMargin);
			Y2Axis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			Y2Axis.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
			Y2Axis.height = virtualHeight - (myHeight - Y2Axis.visibleSize);
		}
		if (Y2Label != null)
		{
			int tmp = 2 + getCountParallelAxis(Y2Axis);
			Y2Label.x = plotters[0].x + plotters[0].visibleWidth + (int)(((double)myWidth * rightMargin * (double)(tmp - 1)) / (double)tmp);
			Y2Label.y = (int)((double)myHeight * topMargin);
			Y2Label.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin + legendMargin)));
			Y2Label.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
		}
		if (legend != null)
		{
			legend.x = (int)((double)myWidth * leftMargin);
			legend.width = (int)((double)myWidth * (1.0D - (leftMargin + leftMargin)));
			legend.y = (int)((double)myHeight * (1.0D - legendMargin));
			legend.height = (int)((double)myHeight * legendMargin);
		}
		adjustSize3d();
		setPlotterSize();
	}

	private void AutoSize_LayoutRight()
	{
		int myHeight = getHeight();
		int myWidth = getWidth();
		if (virtualWidth < myWidth)
			virtualWidth = myWidth;
		if (virtualHeight < myHeight)
			virtualHeight = myHeight;
		plotters[0].visibleWidth = (int)((double)myWidth * (1.0D - (legendMargin + leftMargin)));
		if (Y2Axis != null)
			plotters[0].visibleWidth = (int)((double)myWidth * (1.0D - (legendMargin + rightMargin + leftMargin)));
		plotters[0].visibleHeight = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin)));
		plotters[0].x = (int)((double)myWidth * leftMargin);
		plotters[0].y = (int)((double)myHeight * topMargin);
		plotters[0].width = virtualWidth - (myWidth - plotters[0].visibleWidth);
		plotters[0].height = virtualHeight - (myHeight - plotters[0].visibleHeight);
		title.x = 0;
		title.y = 0;
		if (XAxis != null && XAxis.xscaleOnTop)
			title.y = virtualHeight - (int)((double)myHeight * bottomMargin);
		title.height = (int)((double)myHeight * topMargin);
		title.width = myWidth;
		if (XAxis != null)
		{
			XAxis.x = (int)((double)myWidth * leftMargin);
			XAxis.y = virtualHeight - (int)((double)myHeight * bottomMargin);
			XAxis.realPosition = (int)((double)myHeight * (1.0D - bottomMargin));
			XAxis.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XAxis.visibleSize = plotters[0].visibleWidth;
			XAxis.width = virtualWidth - (myWidth - XAxis.visibleSize);
		}
		if (YAxis != null)
		{
			YAxis.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
			YAxis.x = (int)((double)myWidth * leftMargin) - YAxis.width;
			YAxis.realPosition = YAxis.x;
			YAxis.y = (int)((double)myHeight * topMargin);
			YAxis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin)));
			YAxis.height = virtualHeight - (myHeight - YAxis.visibleSize);
		}
		if (XLabel != null)
		{
			XLabel.height = (int)((double)myHeight * (bottomMargin / (double)(2 + getCountParallelAxis(XAxis))));
			XLabel.x = (int)((double)myWidth * leftMargin);
			XLabel.y = myHeight - XLabel.height;
			if (XAxis != null && XAxis.xscaleOnTop)
				XLabel.y = 0;
			XLabel.width = (int)((double)myWidth * (1.0D - (legendMargin + leftMargin)));
		}
		if (YLabel != null)
		{
			YLabel.x = 0;
			YLabel.y = (int)((double)myHeight * topMargin);
			YLabel.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin)));
			YLabel.width = (int)((double)myWidth * (leftMargin / (double)(2 + getCountParallelAxis(YAxis))));
		}
		if (Y2Axis != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Label != null)
			plotters[0].width = (int)((double)plotters[0].width - ((double)myWidth * secondYAxisMargin) / 2D);
		if (Y2Axis != null)
		{
			Y2Axis.x = plotters[0].x + plotters[0].width;
			Y2Axis.realPosition = plotters[0].x + plotters[0].visibleWidth;
			Y2Axis.y = (int)((double)myHeight * topMargin);
			Y2Axis.visibleSize = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin)));
			Y2Axis.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
			Y2Axis.height = virtualHeight - (myHeight - Y2Axis.visibleSize);
		}
		if (Y2Label != null)
		{
			int tmp = 2 + getCountParallelAxis(Y2Axis);
			Y2Label.x = plotters[0].x + plotters[0].visibleWidth + (int)(((double)myWidth * rightMargin * (double)(tmp - 1)) / (double)tmp);
			Y2Label.y = (int)((double)myHeight * topMargin);
			Y2Label.height = (int)((double)myHeight * (1.0D - (topMargin + bottomMargin)));
			Y2Label.width = (int)(((double)myWidth * rightMargin) / (double)(2 + getCountParallelAxis(Y2Axis)));
		}
		if (legend != null)
		{
			legend.x = (int)((double)myWidth * (1.0D - legendMargin));
			legend.width = (int)((double)myWidth * legendMargin);
			legend.y = (int)((double)myHeight * topMargin);
			legend.height = (int)((double)myHeight * 0.5D);
		}
		adjustSize3d();
		setPlotterSize();
	}

	private void adjustSize3d()
	{
		boolean D3 = false;
		for (int i = 0; i < plottersCount; i++)
		{
			if (plotters[i] instanceof BarPlotter3D)
				D3 = true;
			if (plotters[i] instanceof LinePlotter3D)
				D3 = true;
			if (D3 && plotters[i].depth == 0)
				plotters[i].depth = 20;
			plotters[i].width = plotters[i].width - plotters[i].depth;
			plotters[i].height = plotters[i].height - plotters[i].depth;
			plotters[i].y = plotters[i].y + plotters[i].depth;
		}

		if (Y2Axis != null)
		{
			Y2Axis.visibleSize = Y2Axis.visibleSize - plotters[0].depth;
			Y2Axis.y = Y2Axis.y;
			Y2Axis.height = Y2Axis.height - plotters[0].depth;
		}
		if (YAxis != null)
		{
			YAxis.visibleSize = YAxis.visibleSize - plotters[0].depth;
			YAxis.y = YAxis.y + plotters[0].depth;
			YAxis.height = YAxis.height - plotters[0].depth;
		}
		if (XAxis != null)
		{
			XAxis.visibleSize = XAxis.visibleSize - plotters[0].depth;
			XAxis.width = XAxis.width - plotters[0].depth;
		}
	}

	private void drawBackImage(ChartGraphics g)
	{
		int ImageW = backImage.getWidth();
		int ImageH = backImage.getHeight();
		if (ImageW == -1 || ImageH == -1)
			return;
		for (int j = 0; j <= virtualWidth; j += ImageW)
		{
			for (int i = 0; i <= virtualHeight; i += ImageH)
				g.drawImage(backImage, j, i);

		}

	}

	protected void addFloationgObject(IFloatingObject obj)
	{
		floatingObjects.addElement(obj);
	}

	protected void placeFloatingObject(IFloatingObject ifloatingobject)
	{
	}

	public void resetSize()
	{
		if (originalVirtualHeight > -1)
			virtualHeight = originalVirtualHeight;
		if (originalVirtualWidth > -1)
			virtualWidth = originalVirtualWidth;
	}

	public void paint(ChartGraphics pg)
	{
		floatingObjects.removeAllElements();
		chartHotAreas.removeAllElements();
		long start = System.currentTimeMillis();
		if (plotters[0] == null || plottersCount <= 0)
		{
			pg.setColor(GraphicsProvider.getColor(ChartColor.RED));
			pg.drawString("Error: No plotters/series have been defined", 30, 30);
			return;
		}
		for (int j = 0; j < plottersCount; j++)
		{
			if (plotters[j].getNeedsAxis() > 0 && XAxis == null)
			{
				pg.setColor(GraphicsProvider.getColor(ChartColor.RED));
				pg.drawString("Error: No X axis have been defined", 30, 30);
				return;
			}
			if (plotters[j].getNeedsAxis() > 1 && YAxis == null)
			{
				pg.setColor(GraphicsProvider.getColor(ChartColor.RED));
				pg.drawString("Error: No Y axis have been defined", 30, 30);
				return;
			}
			if (plottersCount > 1 && !plotters[j].getCombinable())
			{
				pg.setColor(GraphicsProvider.getColor(ChartColor.RED));
				pg.drawString("Error: These plotters cannot be combined", 30, 30);
				return;
			}
		}

		ChartGraphics gScroll = pg;
		ChartGraphics gBack = pg;
		ChartGraphics g = pg;
		if (lastWidth != width || lastHeight != height)
		{
			repaintAll = true;
			lastWidth = width;
			lastHeight = height;
		}
		if (originalVirtualHeight == -1)
			originalVirtualHeight = virtualHeight;
		if (originalVirtualWidth == -1)
			originalVirtualWidth = virtualWidth;
		if (!withScroll)
			repaintAlways = true;
		if (repaintAlways)
			repaintAll = true;
		if (autoSize)
		{
			if (!withScroll)
			{
				virtualHeight = originalVirtualHeight;
				virtualWidth = originalVirtualWidth;
			}
			AutoSize();
		}
		try
		{
			if (doubleBuffering && (repaintAll || finalImage == null))
			{
				if (finalImage != null)
					finalImage.dispose();
				finalImage = GraphicsProvider.createImage(getWidth(), getHeight());
			}
		}
		catch (Exception e) { }
		if (finalImage != null)
		{
			g = finalImage.getGraphics();
			gScroll = g;
			gBack = g;
		}
		if (withScroll)
		{
			if (repaintAll || chartImage == null)
			{
				if (chartImage != null)
					chartImage.dispose();
				chartImage = GraphicsProvider.createImage(virtualWidth, virtualHeight);
			}
			gScroll = chartImage.getGraphics();
			if (repaintAll || backTmpImage == null)
			{
				if (backTmpImage != null)
					backTmpImage.dispose();
				backTmpImage = GraphicsProvider.createImage(virtualWidth, virtualHeight);
			}
			gBack = backTmpImage.getGraphics();
		}
		if (virtualWidth > width && XAxis.stackAdditionalAxis)
		{
			XAxis.stackAdditionalAxis = false;
			System.err.println("Warning: additional axis cannot be stacked if using scroll.");
			if (XAxis.getTargetZones().length > 0)
			{
				XAxis.removeTargetZones();
				System.err.println("Warning: axis target zones not compatible scroll.");
			}
		}
		if (virtualHeight > height && YAxis.stackAdditionalAxis)
		{
			YAxis.stackAdditionalAxis = false;
			System.err.println("Warning: additional axis cannot be stacked if using scroll.");
			if (YAxis.getTargetZones().length > 0)
			{
				YAxis.removeTargetZones();
				System.err.println("Warning: axis target zones not compatible scroll.");
			}
		}
		if (repaintAll)
		{
			if (back != null)
				back.draw(gBack, 0, 0, virtualWidth, virtualHeight);
			if (backImage != null)
				drawBackImage(gBack);
		}
		if (withScroll && (backImage != null || back != null))
		{
			if (repaintAll)
				gScroll.drawImage(backTmpImage, 0, 0, virtualWidth, virtualHeight, 0, 0, virtualWidth, virtualHeight);
			g.drawImage(backTmpImage, 0, 0, getWidth(), getHeight(), offsetX, offsetY, getWidth() + offsetX, getHeight() + offsetY);
		}
		if (plotters[0].XScale != null)
		{
			plotters[0].XScale.screenMax = plotters[0].x + plotters[0].width;
			plotters[0].XScale.screenMaxMargin = (int)((double)plotters[0].XScale.screenMax * (1.0D - axisMargin));
			if (fullXAxis)
				plotters[0].XScale.screenMaxMargin = plotters[0].XScale.screenMax;
			plotters[0].XScale.screenMin = plotters[0].x;
		}
		if (plotters[0].YScale != null)
		{
			plotters[0].YScale.screenMax = plotters[0].y + plotters[0].height;
			plotters[0].YScale.screenMaxMargin = (int)((double)plotters[0].YScale.screenMax * (1.0D - axisMargin));
			plotters[0].YScale.screenMin = plotters[0].y;
		}
		if (plotters[0].Y2Scale != null)
		{
			plotters[0].Y2Scale.screenMax = (plotters[0].y + plotters[0].height) - plotters[0].depth;
			plotters[0].Y2Scale.screenMaxMargin = (int)((double)plotters[0].Y2Scale.screenMax * (1.0D - axisMargin));
			plotters[0].Y2Scale.screenMin = plotters[0].y - plotters[0].depth;
		}
		if (repaintAll)
		{
			int plotterBackWidth = plotters[0].width;
			int plotterBackHeight = plotters[0].height;
			if (XAxis != null)
				plotterBackWidth = XAxis.width;
			if (YAxis != null)
				plotterBackHeight = YAxis.height;
			plotters[0].plotBackground(gScroll, plotterBackWidth, plotterBackHeight, offsetX, offsetY);
		}
		title.chart = this;
		title.draw(g);
		if (repaintAll)
		{
			if (XAxis != null)
				XAxis.chart = this;
			if (YAxis != null)
				YAxis.chart = this;
			if (Y2Axis != null)
				Y2Axis.chart = this;
			setPositionStackedAxis(XAxis);
			setPositionStackedAxis(YAxis);
			setPositionStackedAxis(Y2Axis);
			if (XAxis != null)
				XAxis.offset = offsetX;
			if (YAxis != null)
				YAxis.offset = offsetY;
			if (Y2Axis != null)
				Y2Axis.offset = offsetY;
			if (XAxis != null)
				XAxis.drawGridBackground(gScroll, YAxis);
			if (YAxis != null)
				YAxis.drawGridBackground(gScroll, XAxis);
			if (Y2Axis != null)
				Y2Axis.drawGridBackground(gScroll, XAxis);
			if (XAxis != null)
				XAxis.drawBackground(gScroll, YAxis);
			if (YAxis != null)
				YAxis.drawBackground(gScroll, XAxis);
			if (Y2Axis != null)
				Y2Axis.drawBackground(gScroll, XAxis);
		}
		paintTargetZones(g, true);
		if (d() != 1 && legend == null)
			legend = new Legend();
		if (legend != null)
		{
			legend.chart = this;
			legend.draw(g);
		}
		if (XLabel != null)
		{
			XLabel.chart = this;
			XLabel.draw(g);
		}
		if (YLabel != null)
		{
			YLabel.chart = this;
			YLabel.draw(g);
		}
		if (Y2Label != null)
		{
			Y2Label.chart = this;
			Y2Label.draw(g);
		}
		if (repaintAll)
		{
			for (int i = 0; i < plottersCount; i++)
			{
				plotters[i].chart = this;
				plotters[i].plot(gScroll);
			}

		}
		if (border != null)
			border.drawRect(g, 0, 0, getWidth() - 1, getHeight() - 1);
		if (chartImage != null)
		{
			int x1 = plotters[0].x;
			int x2 = plotters[0].x + plotters[0].visibleWidth;
			int y1 = plotters[0].y - plotters[0].depth;
			int y2 = (plotters[0].y - plotters[0].depth) + plotters[0].visibleHeight;
			g.drawImage(chartImage, x1, y1, x2, y2, x1 + offsetX, y1 + offsetY, x2 + offsetX, y2 + offsetY);
		}
		if (chartListeners != null)
		{
			for (int i = 0; i < chartListeners.size(); i++)
				((ChartListener)chartListeners.elementAt(i)).paintUserExit(this, g);

		}
		if (XAxis != null)
		{
			XAxis.offset = offsetX;
			XAxis.drawForeground(g, YAxis);
		}
		if (YAxis != null)
		{
			YAxis.offset = offsetY;
			YAxis.drawForeground(g, XAxis);
		}
		if (Y2Axis != null)
		{
			Y2Axis.offset = offsetY;
			Y2Axis.drawForeground(g, XAxis);
		}
		paintTargetZones(g, false);
		paintNotes(g);
		paintTips(g);
		if (finalImage != null)
			pg.drawImage(finalImage, 0, 0, getWidth(), getHeight(), 0, 0, getWidth(), getHeight());
		repaintAll = false;
		if (gScroll != pg)
			gScroll.dispose();
		if (gBack != pg)
			gBack.dispose();
		if (g != pg)
			g.dispose();
	}

	public void addSerie(DataSerie s)
	{
		plotters[0].addSerie(s);
	}

	public void dispose()
	{
		for (int i = 0; i < plottersCount; i++)
		{
			if (plotters[i] == null)
				continue;
			for (int j = 0; j < plotters[i].getSeriesCount(); j++)
			{
				if (!(plotters[i].getSerie(j) instanceof LineDataSerie))
					continue;
				LineDataSerie lSerie = (LineDataSerie)plotters[i].getSerie(j);
				if (lSerie.icon != null)
					lSerie.icon.dispose();
			}

		}

		if (chartImage != null)
			chartImage.dispose();
		if (finalImage != null)
			finalImage.dispose();
		if (backTmpImage != null)
			backTmpImage.dispose();
		if (backImage != null)
			backImage.dispose();
		stopUpdater();
	}

	public void saveToFile(OutputStream os, String psFormat)
		throws Exception
	{
		ChartImage image;
		ChartGraphics g;
		image = GraphicsProvider.createImage(width, height);
		g = null;
		g = image.getGraphics();
		paint(g);
		image.saveToStream(psFormat, os);
		if (g != null)
			g.dispose();
		image.dispose();
		break MISSING_BLOCK_LABEL_70;
		Exception exception;
		exception;
		if (g != null)
			g.dispose();
		image.dispose();
		throw exception;
	}

	public void saveToFile(String psFile, String psFormat)
		throws Exception
	{
		saveToFile(((OutputStream) (new FileOutputStream(psFile))), psFormat);
	}

	private void paintNotes(ChartGraphics g)
	{
		if (g == null)
			return;
		for (int i = 0; i < notes.size(); i++)
		{
			ChartLabel label = new ChartLabel((String)notes.elementAt(i), "", false, false);
			label.initialize(g, this);
			label.paint(g, 0, 0, 0, 0);
		}

	}

	private void paintTips(ChartGraphics g)
	{
		showingTip = false;
		String tipStr = "";
		if (showTips && selectedSerie != null && selectedSeriePoint >= 0 && selectedSerie.tips != null && selectedSerie.tips.length > selectedSeriePoint)
			tipStr = selectedSerie.tips[selectedSeriePoint];
		if (showTips && selectedLabel != null)
			tipStr = selectedLabel.getTip();
		if (tipStr != null && tipStr.length() > 0)
		{
			String tip[] = ChartLoader.convertList(tipStr, "\\n");
			g.setFont(tipFont);
			String val = (new StringBuilder()).append("").append((int)currentValueY).toString();
			int he = g.getFontHeight() + 4;
			int wi = 4;
			for (int h = 0; h < tip.length; h++)
				if (g.getFontWidth(tip[h]) + 4 > wi)
					wi = g.getFontWidth(tip[h]) + 4;

			g.setColor(tipColor);
			g.fillRect(currentX, currentY - he * tip.length, wi, he * tip.length);
			g.setColor(tipFontColor);
			g.drawRect(currentX, currentY - he * tip.length, wi, he * tip.length);
			for (int h = 0; h < tip.length; h++)
				g.drawString(tip[h], currentX + 2, currentY - 2 - he * (tip.length - h - 1));

			showingTip = true;
			return;
		}
		if (showPosition && currentX > 0 && currentY > 0 && currentX < XAxis.scale.screenMax && currentX > XAxis.scale.screenMin && currentY < YAxis.scale.screenMax && currentY > YAxis.scale.screenMin)
		{
			String txt = (new StringBuilder()).append("").append(currentValueY).toString();
			String sFormat = YAxis.scaleLabelFormat;
			if (sFormat.length() == 0)
				sFormat = "#";
			if (YAxis != null && sFormat.length() > 0)
			{
				DecimalFormat df = null;
				if (numberLocale == null)
				{
					df = new DecimalFormat(sFormat);
				} else
				{
					NumberFormat nf = NumberFormat.getNumberInstance(new Locale(numberLocale, ""));
					df = (DecimalFormat)nf;
					df.applyPattern(sFormat);
				}
				txt = df.format(new Double(currentValueY));
			}
			g.setFont(tipFont);
			int he = g.getFontHeight() + 4;
			int wi = g.getFontWidth((new StringBuilder()).append(txt).append("  ").toString());
			g.setColor(tipColor);
			g.fillRect(currentX, currentY - he, wi, he);
			g.setColor(tipFontColor);
			g.drawRect(currentX, currentY - he, wi, he);
			showingTip = true;
			g.drawString(txt, currentX + 2, currentY - 2);
		}
	}

	public void mouseClick()
	{
		if (selectedSerie != null && selectedSeriePoint >= 0 || selectedLabel != null)
		{
			triggerEvent(5);
			return;
		} else
		{
			triggerEvent(6);
			return;
		}
	}

	private void triggerEvent(int event)
	{
		for (int i = 0; i < chartListeners.size(); i++)
			((ChartListener)chartListeners.elementAt(i)).chartEvent(this, event);

	}

	public void mouseMoved(int eX, int eY)
	{
		if (plotters[0] == null)
			return;
		currentValueX = 0.0D;
		currentValueY = 0.0D;
		currentValueY2 = 0.0D;
		currentX = eX;
		currentY = eY;
		Object previousSelectedObject = selectedSerie;
		int previousPoint = selectedSeriePoint;
		if (selectedSerie == null && selectedLabel != null)
			previousSelectedObject = selectedLabel;
		selectedSerie = null;
		selectedLabel = null;
		selectedSeriePoint = -1;
		if (XAxis != null)
			currentValueX = XAxis.scale.getValue(currentX + offsetX);
		if (YAxis != null)
		{
			currentValueY = YAxis.scale.getValue(currentY + offsetY);
			if (Y2Axis != null)
				currentValueY2 = Y2Axis.scale.getValue(currentY + offsetY);
		}
		if (activateSelection)
		{
			for (int h = 0; h < plotters.length && plotters[h] != null; h++)
			{
label0:
				for (int k = 0; k < plotters[h].getSeriesCount(); k++)
				{
					DataSerie d = plotters[h].getSerie(k);
					int i = 0;
					do
					{
						if (i >= d.hotAreas.size())
							continue label0;
						if (((Polygon)d.hotAreas.elementAt(i)).contains(currentX + offsetX, currentY + offsetY))
						{
							boolean triggerEnter = false;
							if (previousSelectedObject == null)
								triggerEnter = true;
							else
							if (previousSelectedObject != d || previousPoint != i)
							{
								triggerEvent(3);
								triggerEnter = true;
							}
							selectedSerie = d;
							selectedSeriePoint = i;
							if (triggerEnter)
								triggerEvent(2);
							continue label0;
						}
						i++;
					} while (true);
				}

			}

			if (selectedSerie == null)
			{
				int i = 0;
				do
				{
					if (i >= chartHotAreas.size())
						break;
					ChartLabel label = (ChartLabel)chartHotAreas.elementAt(i);
					if (label.clickableArea.contains(currentX + offsetX, currentY + offsetY))
					{
						selectedLabel = label;
						break;
					}
					i++;
				} while (true);
			}
			if (Math.abs(currentX - cursorLastX) > 2 || Math.abs(currentY - cursorLastY) > 2)
			{
				cursorLastX = currentX;
				cursorLastY = currentY;
				triggerEvent(4);
			}
		}
		if (previousSelectedObject != null && selectedSerie == null && selectedLabel == null)
			triggerEvent(3);
	}

	public void startUpdater()
	{
		stopped = false;
		deamon = new Updater();
		deamon.chart = this;
		(new Thread(deamon)).start();
	}

	public void stopUpdater()
	{
		stopped = true;
		if (deamon != null)
			deamon.stop = true;
		deamon = null;
	}

	public String getHTMLImageMap(String name)
	{
		String html = (new StringBuilder()).append("<MAP NAME=\"").append(name).append("\" >").toString();
		boolean hasContent = false;
		Chart c = this;
label0:
		for (int p = 0; p < c.plotters.length; p++)
		{
			if (c.plotters[p] == null)
				continue;
			int s = 0;
			do
			{
				if (s >= c.plotters[p].getSeriesCount())
					continue label0;
				DataSerie se = c.plotters[p].getSerie(s);
				for (int a = 0; a < se.hotAreas.size(); a++)
				{
					Polygon po = (Polygon)se.hotAreas.elementAt(a);
					html = (new StringBuilder()).append(html).append("<AREA SHAPE=POLY COORDS=\"").toString();
					for (int j = 0; j < po.size(); j++)
					{
						if (j > 0)
							html = (new StringBuilder()).append(html).append(", ").toString();
						html = (new StringBuilder()).append(html).append("").append(po.getX(j)).append(", ").append(po.getY(j)).toString();
					}

					html = (new StringBuilder()).append(html).append("\"").toString();
					String tip = "";
					if (c.showTips)
					{
						if (c.plotters[p].getSerie(s).tips != null && c.plotters[p].getSerie(s).tips.length > a)
							tip = c.plotters[p].getSerie(s).tips[a];
						tip = replaceStr(tip, "\\n", "");
						if (tip.length() > 0)
							hasContent = true;
						html = (new StringBuilder()).append(html).append(" ALT=\"").append(tip).append("\"").toString();
						html = (new StringBuilder()).append(html).append(" TITLE=\"").append(tip).append("\"").toString();
					}
					String link = "";
					if (c.plotters[p].getSerie(s).htmlLinks != null && c.plotters[p].getSerie(s).htmlLinks.length > a)
						link = c.plotters[p].getSerie(s).htmlLinks[a];
					if (link.length() > 0)
					{
						html = (new StringBuilder()).append(html).append(" HREF=\"").append(link).append("\"").toString();
						if (link.length() > 0)
							hasContent = true;
					}
					if (htmlLinkTarget.length() > 0)
						html = (new StringBuilder()).append(html).append(" TARGET=\"").append(htmlLinkTarget).append("\"").toString();
					html = (new StringBuilder()).append(html).append(">").toString();
				}

				s++;
			} while (true);
		}

		for (int i = 0; i < chartHotAreas.size(); i++)
		{
			ChartLabel label = (ChartLabel)chartHotAreas.elementAt(i);
			Polygon po = label.clickableArea;
			html = (new StringBuilder()).append(html).append("<AREA SHAPE=POLY COORDS=\"").toString();
			for (int j = 0; j < po.size(); j++)
			{
				if (j > 0)
					html = (new StringBuilder()).append(html).append(", ").toString();
				html = (new StringBuilder()).append(html).append("").append(po.getX(j)).append(", ").append(po.getY(j)).toString();
			}

			html = (new StringBuilder()).append(html).append("\"").toString();
			String tip = "";
			if (c.showTips)
			{
				if (label.getTip() != null)
					tip = label.getTip();
				tip = replaceStr(tip, "\\n", "");
				if (tip.length() > 0)
					hasContent = true;
				html = (new StringBuilder()).append(html).append(" ALT=\"").append(tip).append("\"").toString();
				html = (new StringBuilder()).append(html).append(" TITLE=\"").append(tip).append("\"").toString();
			}
			String link = "";
			if (label.getClickInfo() != null)
				link = label.getClickInfo();
			if (link.length() > 0)
			{
				html = (new StringBuilder()).append(html).append(" HREF=\"").append(link).append("\"").toString();
				if (link.length() > 0)
					hasContent = true;
			}
			if (htmlLinkTarget.length() > 0)
				html = (new StringBuilder()).append(html).append(" TARGET=\"").append(htmlLinkTarget).append("\"").toString();
			html = (new StringBuilder()).append(html).append(">").toString();
		}

		html = (new StringBuilder()).append(html).append("</MAP>").toString();
		if (!hasContent)
			return "";
		else
			return html;
	}

	private static String replaceStr(String s, String sub1, String sub2)
	{
		for (int p = s.indexOf(sub1); p >= 0; p = s.indexOf(sub1))
			s = (new StringBuilder()).append(s.substring(0, p)).append(sub2).append(s.substring(p + sub1.length(), s.length())).toString();

		return s;
	}

}
